/*
 * Copyright 2009 SHOP.COM
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.shop.opensocial.mediated.shindig.factories;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Factory for converting between two enum types that have the same names
 *
 * @author Jordan Zimmerman
 */
public class EnumMapper<FROM extends Enum<FROM>, TO extends Enum<TO>>
{
	/**
	 * @param fromValues list of source enums
	 * @param toValues list of destination enums
	 */
	public EnumMapper(FROM[] fromValues, TO[] toValues)
	{
		Map<FROM, TO>		work = new HashMap<FROM, TO>();
		Map<TO, FROM>		reverseWork = new HashMap<TO, FROM>();
		for ( FROM f : fromValues )
		{
			for ( TO t : toValues )
			{
				if ( f.name().equalsIgnoreCase(t.name()) )
				{
					work.put(f, t);
					reverseWork.put(t, f);
				}
			}
		}
		fTypeToTypeMap = Collections.unmodifiableMap(work);
		fTypeToTypeReverseMap = Collections.unmodifiableMap(reverseWork);
	}

	/**
	 * Return the corresponding value
	 *
	 * @param f in value
	 * @return out value or null
	 */
	public TO			to(FROM f)
	{
		return fTypeToTypeMap.get(f);
	}

	/**
	 * Return the corresponding value
	 *
	 * @param f in value
	 * @param defaultValue value to return of input value isn't found or is null
	 * @return out value or null
	 */
	public TO			to(FROM f, TO defaultValue)
	{
		TO v = fTypeToTypeMap.get(f);
		return (v != null) ? v : defaultValue;
	}

	/**
	 * Return the corresponding value
	 *
	 * @param t in value
	 * @return out value or null
	 */
	public FROM			from(TO t)
	{
		return fTypeToTypeReverseMap.get(t);
	}

	private final Map<FROM, TO> 		fTypeToTypeMap;
	private final Map<TO, FROM> 		fTypeToTypeReverseMap;
}
